home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / MSDOS / (m)aak / UNCRUNCH.PAS < prev   
Pascal/Delphi Source File  |  1987-06-20  |  8KB  |  153 lines

  1. procedure UNCRUNCH (var Addr1,Addr2; BlkLen:Integer);
  2.  
  3. {This is the flash display routine used to display crunched TheDraw image
  4.  files.  It uses a custom protocol for reproducing a image with any
  5.  possible color combinations.  The control codes below #32 are reserved
  6.  for this function.  The following data structure shows the format of a
  7.  sequence.  Not all operations use the optional bytes <x> or <y>..
  8.  
  9.  Data Structure:  <current byte>[<x>[<y>]]
  10.  
  11.     0..15 = New Foreground Color
  12.    16..23 = New Background Color
  13.        24 = Go down to next line, return to same horizontal position as when
  14.             routine was started (akin to a c/r).
  15.        25 = Displays <x> number of spaces.
  16.        26 = Displays <x> number of <y>.  Also used to display ANY characters
  17.             below #32.  This function is the only way to do this although it
  18.             uses three bytes.  Otherwise the code would be interpreted as
  19.             another command.
  20.  
  21.  ----------------------------------------------------------------------------
  22.  
  23.  To use this routine you call the procedure with the ImageData as the
  24.  first parameter, the display address as the second parameter, and the
  25.  length of the ImageData as the third parameter.
  26.  
  27.  Assume we have a ImageData file of a 40 characters by 10 lines block.  Also
  28.  the following defintions.  ie:
  29.  
  30.    type ScreenType = array [0..3999] of Byte;
  31.    var  ScreenAddr : ScreenType absolute $B800:$0000;
  32.  
  33.    const ImageData : array [1..467] of Byte =
  34.      (...list of image bytes here...);
  35.  
  36.    begin
  37.      UnCrunch (ImageData,ScreenAddr[ (34*2) + (5*160) -162],467);
  38.    end;
  39.  
  40.  
  41.  SCREENADDR is a variable mapped to the same location as the physical video
  42.  addresses (using Turbo's absolute addressing).   The fairly complex array
  43.  address in the call tells UnCrunch where to start displaying the ImageData
  44.  40 character by 10 line block.  The 34*2 indicates the horizontal position
  45.  number 34 with the 5*160 indicating line number 5.  This is similar to a
  46.  Turbo GOTOXY (34,5) statement, except it works for UnCrunch instead.
  47.  
  48.  The value of 467 used in the call is the length of the array as indicated
  49.  in the CONST statement.
  50.  
  51.  UnCrunch remembers the horizontal (X) starting position when it goes down
  52.  to the next line.  This allows you to display the ImageData block correctly
  53.  at any position on the screen.   ie:
  54.  
  55.    +-------------------------------------------------+
  56.    |                                                 |
  57.    |                                                 | <- Pretend this
  58.    |                                                 |    is the video
  59.    |           ┌─────────────────────┐               |    display.
  60.    |           │█████████████████████│               |
  61.    |           │█████████████████████│               |
  62.    |           │██ ImageData block ██│               |
  63.    |           │█████████████████████│               |
  64.    |           │█████████████████████│               |
  65.    |           │█████████████████████│               |
  66.    |           └─────────────────────┘               |
  67.    |                                                 |
  68.    |                                                 |
  69.    |                                                 |
  70.    +-------------------------------------------------+
  71.  
  72.  
  73.  The ImageData block could just as well have been display in the upper-left
  74.  corner of the screen with:
  75.      UNCRUNCH (ImageData,ScreenAddr[ (1*2) + (1*160) -162],467);
  76.  
  77.  Notice the array address changed to the equivilant of GOTOXY (1,1);
  78.  
  79.  To display the block in the lower-right corner you would use:
  80.      UNCRUNCH (ImageData,ScreenAddr[ (40*2) + (15*160) -162],467);
  81.  
  82.  The block is 40 characters wide by 10 lines deep.  Therefore to display
  83.  such a large block, we must display the block at GOTOXY (40,15);
  84.  
  85.  
  86.  
  87.  Obviously I have been attempting to describe this procedure by use of
  88.  examples.  This is done because I feel it is the easiest and clearest way
  89.  of explaining this procedure.  It was designed to be as simple as possible,
  90.  however for some people the best way to learn it is to experiment.  Try
  91.  creating a program using the above example information.  Use TheDraw to
  92.  make a 40 by 10 block (or any size) to experiment with.  Good luck.  If
  93.  you can devise a better way of explaining this, please share your labors
  94.  with me.   Others will surely benifit.   Thanks!
  95.  
  96. }
  97. begin
  98.   inline (
  99.     $1E/               {       PUSH    DS}
  100.     $C5/$B6/Addr1/     {       LDS     SI,[BP+Addr1]  ;Source Address}
  101.     $C4/$BE/Addr2/     {       LES     DI,[BP+Addr2]  ;Destination Addr}
  102.     $8B/$8E/BlkLen/    {       MOV     CX,[BP+BlkLen] ;Length of block}
  103.     $8B/$D7/           {       MOV     DX,DI          ;Save X coord for later.}
  104.     $B4/$00/           {       MOV     AH,0           ;Current attributes.}
  105.     $AC/               {LOOPA: LODSB                  ;Get next character.}
  106.     $3C/$10/           {       CMP     AL,16          ;If less than 16,}
  107.     $73/$07/           {       JNC     Short BackG    ;then change the}
  108.     $80/$E4/$F0/       {       AND     AH,0F0H        ;foreground color.}
  109.     $0A/$E0/           {       OR      AH,AL}
  110.     $EB/$44/           {       JMP     Short Next}
  111.     $3C/$18/           {BackG: CMP     AL,24          ;If less than 24,}
  112.     $74/$13/           {       JZ      Short NextL    ;then change the}
  113.     $73/$19/           {       JNC     Short Multi    ;background color.}
  114.     $2C/$10/           {       SUB     AL,16}
  115.     $02/$C0/           {       ADD     AL,AL}
  116.     $02/$C0/           {       ADD     AL,AL}
  117.     $02/$C0/           {       ADD     AL,AL}
  118.     $02/$C0/           {       ADD     AL,AL}
  119.     $80/$E4/$0F/       {       AND     AH,0FH}
  120.     $0A/$E0/           {       OR      AH,AL}
  121.     $EB/$2D/           {       JMP     Short Next}
  122.     $81/$C2/$A0/$00/   {NextL: ADD     DX,160         ;If equal to 24,}
  123.     $8B/$FA/           {       MOV     DI,DX          ;then jump down to}
  124.     $EB/$25/           {       JMP     Short Next     ;the next line.}
  125.     $3C/$1A/           {Multi: CMP     AL,26          ;If equal to 26,}
  126.     $75/$0B/           {       JNZ     Space          ;then using the}
  127.     $AC/               {       LODSB                  ;following two codes}
  128.     $49/               {       DEC     CX             ;Adjust main counter.}
  129.     $51/               {       PUSH    CX             ;display as many of}
  130.     $32/$ED/           {       XOR     CH,CH          ;whatever the user}
  131.     $8A/$C8/           {       MOV     CL,AL          ;wants.}
  132.     $AC/               {       LODSB                  ;Get character.}
  133.     $EB/$0D/$90/       {       JMP     Start          ;Use below loop.}
  134.     $3C/$19/           {Space: CMP     AL,25          ;If equal to 25,}
  135.     $75/$11/           {       JNZ     Short Lettr    ;then using the}
  136.     $AC/               {       LODSB                  ;following code as}
  137.     $51/               {       PUSH    CX             ;a count, output}
  138.     $32/$ED/           {       XOR     CH,CH          ;said number of}
  139.     $8A/$C8/           {       MOV     CL,AL          ;spaces.}
  140.     $B0/$20/           {       MOV     AL,32}
  141.     $0B/$C9/           {Start: OR      CX,CX          ;Abort if already}
  142.     $74/$03/           {       JZ      Stop           ;at zilch.}
  143.     $AB/               {LOOPB: STOSW}
  144.     $E2/$FD/           {       LOOP    LOOPB}
  145.     $59/               {Stop:  POP     CX}
  146.     $49/               {       DEC     CX             ;Adjust main counter.}
  147.     $AB/               {Lettr: STOSW                  ;Save screen letter.}
  148.     $0B/$C9/           {Next:  OR      CX,CX          ;Get next, unless}
  149.     $74/$02/           {       JZ      Done           ;CX has already}
  150.     $E2/$AA/           {       LOOP    LOOPA          ;gone to zero.}
  151.     $1F);              {Done:  POP     DS}
  152. end; {UNCRUNCH}
  153.